﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using FlashCards.SL.FlashCardCreator.DataService;
using FlashCards.SL.FlashCardCreator.ViewModels.Commands;
using FlashCards.Dto;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.ServiceModel;
using FlashCards.SL.FlashCardCreator.Utils;
using FlashCards.SL.FlashCardCreator.Events;
using System.Text;

namespace FlashCards.SL.FlashCardCreator.ViewModels
{
    public class MainPageViewModel : BaseViewModel
    {
        public FlashcardSetViewModel EditContext { get; set; }
        public bool IsInEditMode { get; set; }
        public event EventHandler<FlashcardSetEventArgs> OnSaveChanges;
        public string _endpointName;

        public MainPageViewModel(FlashcardSet set, string endpointName)
        {
            CurrentUser = ((FlashCardsSilverlightApp)Application.Current).CurrentUser as User;
            InitializeCommands();
            InitializeFlashcardSet(set);
            IsInEditMode = true;
            _endpointName = endpointName;
        }

        public MainPageViewModel(string endpointName)
        {
            CurrentUser = ((FlashCardsSilverlightApp)Application.Current).CurrentUser as User;
            InitializeCommands();
            InitializeFlashcardSet();
            _endpointName = endpointName;
        }

        public User CurrentUser { get; set; }

        private void InitializeFlashcardSet(FlashcardSet set)
        {
            EditContext = new FlashcardSetViewModel(set);
        }

        private void InitializeFlashcardSet()
        {
            var newSet = new FlashcardSet()
            {
                Creator = CurrentUser,
                DateModified = DateTime.Now,
                IsPublic = true,
                Flashcards = new List<Flashcard>(),
                Category = new Category()
            };

            InitializeFlashcardSet(newSet);
        }

        #region COMMANDS

        public ICommand SaveChangesCommand { get; private set; }
        public ICommand ExportToCsvCommand { get; private set; }
        public ICommand ImportFromCsvCommand { get; private set; }

        private void InitializeCommands()
        {
            SaveChangesCommand = new Command(SaveChanges);
            ExportToCsvCommand = new Command(ExportToCsv);
            ImportFromCsvCommand = new Command(ImportFromCsv);
        }

        void SaveChanges()
        {
            var flashcardSet = EditContext.FlashcardSet;
            if (FlashcardSetValidator.Validate(flashcardSet))
            {
                flashcardSet.DateModified = DateTime.Now;
                XmlSerializer ser = new XmlSerializer(typeof(FlashcardSet));
                StringWriter writer = new StringWriter();
                ser.Serialize(writer, flashcardSet);


                var proxy = new FlashCardCreator.DataService.SilverlightServiceClient(_endpointName);

                if (IsInEditMode)
                {
                    proxy.UpdateExistingSetCompleted += (o, e) =>
                        {
                            if (e.Error != null)
                            {
                                if (e.Error is FaultException<CustomFault>)
                                {
                                    var fault = e.Error as FaultException<CustomFault>;
                                    MessageBox.Show(fault.Message + fault.Detail.CustomFaultString);
                                }
                            }
                            else if (e.Cancelled == false)
                            {
                                MessageBox.Show("Saved");
                            }
                        };
                    proxy.UpdateExistingSetAsync(writer.ToString());
                }
                else
                {

                    proxy.AddNewFlashcardSetCompleted += (o, e) =>
                        {
                            if (e.Error != null)
                            {
                                if (e.Error is FaultException<CustomFault>)
                                {
                                    var fault = e.Error as FaultException<CustomFault>;
                                    MessageBox.Show(fault.Message + fault.Detail.CustomFaultString);
                                }
                            }
                            else if (e.Cancelled == false)
                            {
                                if (!string.IsNullOrEmpty(e.Result))
                                {
                                    var stringReader = new StringReader(e.Result);
                                    var serializer = new XmlSerializer(typeof(FlashcardSet));
                                    var set = serializer.Deserialize(stringReader) as FlashcardSet;

                                    EditContext.UpdateFlashcardSet(set);
                                    OnSaveChanges(this, new FlashcardSetEventArgs(EditContext.FlashcardSet.Id));
                                }
                                MessageBox.Show("Saved");
                            }
                        };
                    //TODO: zamienić to na eventy obslugiwane po stronie aplikacji
                    var groupId = ((FlashCardsSilverlightApp)Application.Current).GroupId;

                    proxy.AddNewFlashcardSetAsync(writer.ToString(), groupId);
                }
            }
            else
            {
                MessageBox.Show("Correct the data");
            }
        }

        void ExportToCsv()
        {
            try
            {
                var csvBuilder = new StringBuilder();
                foreach (var item in EditContext.FlashcardSet.Flashcards)
                {
                    var definitionString = Encoding.UTF8.GetString(item.Definition.Data, 0, item.Definition.Data.Length);
                    var termString = Encoding.UTF8.GetString(item.Term.Data, 0, item.Term.Data.Length);
                    csvBuilder.AppendLine(string.Format("\"{0}\",\"{1}\"", termString.Replace(',', ';'), definitionString.Replace(',', ';')));
                }

                var dialog = new SaveFileDialog();
                dialog.DefaultExt = ".csv";
                dialog.Filter = "CSV files|*.csv";
                dialog.ShowDialog();

                if (!string.IsNullOrEmpty(dialog.SafeFileName))
                {
                    using (var writer = dialog.OpenFile())
                    {
                        var bytes = Encoding.UTF8.GetBytes(csvBuilder.ToString());
                        writer.Write(bytes, 0, bytes.Length);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Something is wrong: {0}", ex.Message));
            }
        }

        void ImportFromCsv()
        {
            try
            {
                var dialog = new OpenFileDialog();
                dialog.Filter = "CSV files|*.csv";
                bool? clickedOkButton = dialog.ShowDialog();

                if (clickedOkButton == true)
                {
                    using (var fileStream = dialog.File.OpenRead())
                    {
                        using (var reader = new StreamReader(fileStream))
                        {
                            var tempFlashcards = new List<Flashcard>();

                            var file = reader.ReadToEnd();

                            var flashcards = file.Split('\n');

                            foreach (var card in flashcards)
                            {
                                if (!string.IsNullOrEmpty(card.Trim()))
                                {
                                    tempFlashcards.Add(new Flashcard
                                        {
                                            DateModified = DateTime.Now,
                                            FlashcardSetId = this.EditContext.FlashcardSet.Id,
                                            Term = new FlashcardPart
                                            {
                                                DateModified = DateTime.Now,
                                                Type = null,
                                                Data = Encoding.UTF8.GetBytes(card.Split(',')[0].Replace("\"", string.Empty))
                                            },
                                            Definition = new FlashcardPart
                                            {
                                                DateModified = DateTime.Now,
                                                Type = null,
                                                Data = Encoding.UTF8.GetBytes(card.Split(',')[1].Replace("\"", string.Empty))
                                            },
                                        });
                                }
                            }

                            this.EditContext.FlashcardSet.Flashcards = tempFlashcards;
                            this.EditContext.InitializeFlashcardsCollection(false);

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        #endregion
    }
}
